﻿using Masa.BuildingBlocks.Caching;
using Masa.BuildingBlocks.Data.UoW;
using Masa.BuildingBlocks.ReadWriteSplitting.Cqrs.Queries;
using Masa.Contrib.Caching.MultilevelCache;
using Masa.Contrib.Dispatcher.Events;
using Masa.CqrsProject.Contexts;
using Masa.CqrsProject.Models;
using Masa.CqrsProject.Repositorys;
using Microsoft.EntityFrameworkCore;
using StackExchange.Redis;

namespace Masa.CqrsProject.Querys
{
    /// <summary>
    /// 订单查询处理器
    /// </summary>
    public class OrderQueryHandler
    {

        private readonly IOrderRepository _orderRepository;
        private readonly IOrderReadRepository _orderReadRepository;

        private readonly IDistributedCacheClient _cacheClient; //分布式缓存

        private readonly IMultilevelCacheClient _multilevelCacheClient; //多级缓存

        /// <summary>
        /// 
        /// </summary>
        public OrderQueryHandler(IOrderRepository orderRepository, IOrderReadRepository orderReadRepository, 
            IDistributedCacheClient distributedCacheClient, IMultilevelCacheClient multilevelCacheClient)

        {
            _orderRepository = orderRepository;
            _orderReadRepository = orderReadRepository;
            _cacheClient = distributedCacheClient;
            _multilevelCacheClient = multilevelCacheClient;
        }

        #region 简单模式

        #endregion

        /// <summary>
        /// 查询订单
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        [EventHandler]
        public async Task GetOrder(GetOrderInfoQuery query)
        {
            Console.WriteLine("查询订单信息");

            //多级缓存（防止缓存击穿）
            var order = _multilevelCacheClient.Get<OrderInfo>("orderInfo_"+query.id.ToString());
            if(order == null)
            {
                order = await _orderRepository.GetOrderAsync(query.id.ToString());
                //缓存查询后的数据，多级缓存全局配置了过期时间
                _multilevelCacheClient.Set<OrderInfo>(query.id.ToString(), order);
            }

            query.Result = order;
        }

        #region 读写分离模式


        /// <summary>
        /// 获取订单列表
        /// </summary>
        /// <returns></returns>
        [EventHandler]
        public async Task GetOrdersAsync(GetOrderListQuery query)
        {
            Console.WriteLine("查询订单列表...");

            //1 从缓存中获取
            List<OrderInfo> list = _cacheClient.Get<List<OrderInfo>>("orderList"); //1 从缓存中获取

            //2 如果缓存中没有，则从数据库中获取
            if (list == null)
            {
                list = await _orderReadRepository.GetOrdersAsync();
                //_cacheClient.Set("orderList", list, TimeSpan.FromMinutes(5)); //2 如果缓存中没有，则从数据库中获取
                CacheEntryOptions options = new CacheEntryOptions
                {
                    AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5)
                };
                _cacheClient.Set("orderList", list, options);
            }
            query.Result = list.ToList();

        }

        #endregion

    }
}
